#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pygtk
pygtk.require('2.0')
import gtk
import codecs
import re
import os
import sys

# formerly - ucs8conv, renamed
#import hipconv
import hip_config
# comment parser
import hipcomment

#conv = hipconv.Repl()
brac = hipcomment.Brackets()

class Text:
    """ text viewer 

    """
    def __init__(self, config):

        # original plain text
        self.base_txt = ""
        self.window3 = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window3.set_resizable(True)
        self.window3.set_border_width(10)
        self.window3.set_size_request(850, 400)

        self.window3.set_border_width(0)
#        self.window3.connect('key_press_event', self.redraw_cb)

        box1 = gtk.VBox(False, 0)
        self.window3.add(box1)
        box1.show()

        box2 = gtk.VBox(False, 3)
        box2.set_border_width(3)
        box1.pack_start(box2, True, True, 0)
        box2.show()

        self.f_select = gtk.FontButton(fontname=None)
        self.f_select.connect('font-set', self.font_cb)

#        self.check1 = gtk.CheckButton("вкл. юникод")
#        self.check1.connect("toggled", self.uni_out)

        self.entry = gtk.Entry()

        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        sw.connect('key_press_event', self.redraw_cb)
        self.textview = gtk.TextView()
        self.textview.set_editable(True)

        self.textbuffer = self.textview.get_buffer()
#        self.iter = gtk.TextIter(self.textbuffer)
        sw.add(self.textview)
        sw.show()
        self.f_select.show()
#        self.check1.show()
        self.entry.show()
        self.entry.connect('key_press_event', self.search_cb)

        self.textview.show()
        box2.pack_start(self.f_select, False, False, 0)
#        box2.pack_start(self.check1, False, False, 0)
        box2.pack_start(sw)
        box2.pack_start(self.entry, False, False, 0)

        self.window3.show()
        self.textview.grab_focus()

        # current position in text
        self.pos = 0

        # regexp to check if the font is ucs-compatible
        # probably not a good idea, if there is some kind of 'kucs.ttf' out there...
        # well, in that case we'll make an exception.
        self.ucs_patt = re.compile(u'ucs', re.U | re.I)

        self.config = config

        # default font
        self.sl_font = self.config.default_font
        self.sl_font_prev = ''
        self.plain_font = 'Tahoma 16'
        self.check_font(self.sl_font)
        if self.config.default_style == 'slavonic':
            self.plain = False
        elif self.config.default_style == 'plain':
            self.plain = True

        if self.config.brackets_off == 'True':
            self.brackets_off = True
        else:
            self.brackets_off = False

    def check_font(self, font):
        '''Change type of conversion according to chosen font-type'''

        if self.ucs_patt.search(font):
            self.uni = 'ucs'
        elif 'Old Standard' in font or 'Hirmos Ponomar' in font:
            self.uni = 'uni_csl'
        else:
            self.uni = 'uni'

        print self.uni

    def font_cb(self, f_button):
        '''Callback to font-select dialog'''

        font = f_button.get_font_name()
        print font

        self.check_font(font)

        self.sl_font = font

        self.ins_txt()
        self.style_txt()

    def ins_txt(self, new_txt=None):
            
        if new_txt:
            self.base_txt = new_txt
        if not self.plain: 
            # parse comments. If 2d argument True, wipe comments
#            conv_txt = brac.repl_brac(self.base_txt, True)[0]
            conv_txt = brac.repl_brac(self.base_txt, self.brackets_off)[0]
            # convert to slavonic typeset
#            conv_txt = conv(conv_txt, self.uni)
#            conv_txt = conv(self.base_txt, self.uni)
            self.textbuffer.set_text(conv_txt)

            # have to 'remember' last used font.
            if self.sl_font == self.plain_font:
                self.sl_font = self.sl_font_prev
        else:
            self.textbuffer.set_text(self.base_txt)
            self.sl_font_prev = self.sl_font
            self.sl_font = self.plain_font

        self.tag_table = self.textbuffer.get_tag_table()
        self.my_text = gtk.TextTag()
        self.tag_table.add(self.my_text)
        self.style_txt()  
        self.f_select.set_font_name(self.sl_font)

        # Here's patch by S. Maryasin, makes %<L%>etters red
        if not self.plain:
            # преобразуем "костыльные" метки \1 и \2 в киноварь
            red = gtk.TextTag()
            self.tag_table.add(red)
            red.set_property("foreground", "red")
            i = self.textbuffer.get_start_iter()
            while i.get_char() != '\0':
                if i.get_char() == '\1': # начало выделения, %<
                    i.forward_char()
                    self.textbuffer.backspace(i, False, True) # удаляем метку
                    start = i.get_offset() # запоминаем позицию
                if i.get_char() == '\2': # конец выделения, %>
                    i.forward_char()
                    self.textbuffer.backspace(i, False, True)
                    self.textbuffer.apply_tag(red, self.textbuffer.get_iter_at_offset(start), i)
                i.forward_char() # next i
            # end of patch. See also changes in ucs8conv

#            self.textview.scroll_to_iter(self.textview.get_start_iter(), 0.0, True, 0.0, 1.0)

    def redraw_cb(self, widget, event):
        """Disable-enable converter for Text wid."""

        keyname = gtk.gdk.keyval_name(event.keyval)
#        print 'key', keyname, 'was pressed', event.keyval
        if keyname == "d" and event.state & gtk.gdk.CONTROL_MASK:
            if not self.plain:
                self.plain = True
                temp_iter = self.textview.get_iter_at_location(0, self.textview.get_visible_rect()[1])
                self.pos = temp_iter.get_line()
#                plain = True
                self.ins_txt(self.base_txt)
    #            self.style_txt()
#                print self.pos
                print self.plain
            else:

                self.plain = False
                temp_iter = self.textview.get_iter_at_location(0, self.textview.get_visible_rect()[1])
                self.pos = temp_iter.get_line()
                self.ins_txt(self.base_txt)
                print self.plain
#            self.style_txt()
#                print self.pos

    def search_cb(self, widget, event):

        keyname = gtk.gdk.keyval_name(event.keyval)
        # search for given substring in buffer
        if keyname == "Return":
            self.search_str = widget.get_text()
            start_iter =  self.textbuffer.get_start_iter()
            found = start_iter.forward_search(self.search_str, 0, None) 
            if found:
                self.match_start, self.match_end = found #add this line to get self.match_start and match_end
                self.textbuffer.select_range(self.match_start, self.match_end)
                self.textview.scroll_to_iter(self.match_start, 0.0, True, 0.0, 1.0)
        elif keyname == "n" and event.state & gtk.gdk.CONTROL_MASK \
        or keyname == "Cyrillic_te" and event.state & gtk.gdk.CONTROL_MASK:
            try:
                start_iter = self.match_end
                found = start_iter.forward_search(self.search_str, 0, None) 
                if found:
                    self.match_start, self.match_end = found
                    self.textbuffer.select_range(self.match_start, self.match_end)
                    self.textview.scroll_to_iter(self.match_start, 0.0, True, 0.0, 1.0)
            except AttributeError:
                print 'no search results'
        elif keyname == "p" and event.state & gtk.gdk.CONTROL_MASK \
        or keyname == "Cyrillic_ze" and event.state & gtk.gdk.CONTROL_MASK:
            try:
                start_iter = self.match_start
                found = start_iter.backward_search(self.search_str, 0, None) 
                if found:
                    self.match_start, self.match_end = found
                    self.textbuffer.select_range(self.match_start, self.match_end)
                    self.textview.scroll_to_iter(self.match_start, 0.0, True, 0.0, 1.0)
            except AttributeError:
                print 'no search results'

    def style_txt(self):
        self.my_text.set_property("font", self.sl_font)
        self.my_text.set_property("wrap-mode", gtk.WRAP_WORD)
#        self.my_text.set_property("wrap-mode", gtk.WRAP_CHAR)
        
        startiter, enditer = self.textbuffer.get_bounds()
        self.textbuffer.apply_tag(self.my_text, startiter, enditer)

        if self.pos:
            # put cursor at the start of the page
            zero_iter = self.textbuffer.get_iter_at_line(self.pos)
            zero_mark = self.textbuffer.create_mark(None, zero_iter)
            self.textbuffer.place_cursor(self.textbuffer.get_iter_at_line(self.pos))
            self.textview.scroll_to_mark(zero_mark, 0.0, True, 0.0, 1.0)
            self.textview.grab_focus()

        self.textview.place_cursor_onscreen()

#TODO: make hidden comments, so that one doesnt have to reload the page to see them
